package com.gitee.swsk33.websockethandlerdemo.handler.websocket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;

/**
 * 简单的二进制（文件）消息处理
 */
@Slf4j
@Component
public class BinaryWebSocketHandler implements WebSocketHandler {

	/**
	 * 连接建立时执行的方法
	 *
	 * @param session WebSocket会话对象
	 */
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		log.info("连接已建立！");
		// 读取一个文件发送
		FileInputStream inputStream = new FileInputStream("C:\\Users\\swsk33\\Pictures\\Saved Pictures\\illust_113986738_20231219_001852.jpg");
		// BinaryMessage也是WebSocketMessage的子类，表示二进制内容消息
		// 构造函数传入二进制内容byte[]字节数组即可
		BinaryMessage message = new BinaryMessage(inputStream.readAllBytes());
		inputStream.close();
		// 会话send方法把消息发给客户端
		session.sendMessage(message);
	}

	/**
	 * 客户端发来消息时执行的方法
	 *
	 * @param session WebSocket会话对象
	 * @param message 客户端发来的消息对象
	 */
	@Override
	public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
		log.info("接收到客户端消息！");
		log.info("消息内容大小：{} 字节", message.getPayloadLength());
		// 读取用户发送来的消息，并解析
		// 向下转型
		BinaryMessage getMessage = (BinaryMessage) message;
		// 二进制消息得到的是ByteBuffer对象，先读取其中字节内容
		// 获取ByteBuffer
		ByteBuffer buffer = getMessage.getPayload();
		// 创建一个字节数组用于读取内容
		byte[] content = new byte[getMessage.getPayloadLength()];
		// 读取ByteBuffer内容至字节数组
		buffer.get(content);
		// 保存内容至文件
		FileOutputStream fileStream = new FileOutputStream("C:\\Users\\swsk33\\Downloads\\a.txt");
		fileStream.write(content);
		fileStream.close();
	}

	/**
	 * 出现错误时的执行方法
	 *
	 * @param session   WebSocket会话对象
	 * @param exception 出现错误的异常
	 */
	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		log.error("出现错误！{}", exception.getMessage());
		// 调用会话的close方法可以主动断连
		session.close();
	}

	/**
	 * 断开连接时执行的方法
	 *
	 * @param session     WebSocket会话对象
	 * @param closeStatus 断开连接的状态码
	 */
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
		log.warn("与客户端断开连接！");
	}

	/**
	 * 是否支持部分消息
	 * 不用管保持默认即可
	 */
	@Override
	public boolean supportsPartialMessages() {
		return false;
	}

}